<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        html,
        body {
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <canvas id="cvs"></canvas>
    <script>
        var w = window.innerHeight;
        var h = window.innerHeight;
        var cvs = document.getElementById('cvs');
        cvs.width = w;
        cvs.height = h;
        var ctx = cvs.getContext('2d');

        var LayerBallNum = 360 / 30,
            // 横向圆周个数 
            LayerIntervalUp = 360 / 30;
        //纵向 
        function Animation() {
            this.init();
        };
        Animation.prototype = {
            isrunning: false,
            init:function () {
                var num = LayerIntervalUp / 2;
                //layer 的数目 画上半球 下半球 
                for (var i = 0; i <= num; i++) {
                    var l = new layer(i, 1);
                    l.draw();
                    var l = new layer(i, -1);
                    l.draw();
                }
            }
        }
        function layer(num, up) {
            this.radius = Math.sqrt(Math.pow(Radius, 2) - Math.pow(Radius * Math.cos(num * Math.PI * 2 /
                LayerBallNum), 2));
            //设定不同经度上的圆周半径 
            this.x = 0;
            this.y = 0;
            this.up = up;
        }

        layer.prototype = {
            setBalls: function (radius) {
                for (var i = 0; i < LayerBallNum; i++) {
                    var angle = 2 * Math.PI / LayerBallNum * i;
                    var b = new ball(radius * Math.cos(angle), radius * Math.sin(angle), this.up * Math.sqrt(
                        Math.pow(Radius, 2) - Math.pow(radius, 2)), 1.5);
                    b.paint();
                    balls.push(b);
                }
            },
            draw: function () {
                ctx.beginPath();
                ctx.arc(vpx, vpy, this.radius, 0, 2 * Math.PI, true);
                ctx.strokeStyle = "#FFF";
                ctx.stroke();
                this.setBalls(this.radius);
            }
        }
        function ball(x, y, z, r) {
            this.x = x;
            this.y = y;
            this.z = z;
            this.r = r;
            this.width = 2 * r;
        }
        ball.prototype = {
            paint: function () {
                var fl = 450
                //焦距 
                ctx.save();
                ctx.beginPath();
                var scale = fl / (fl - this.z);
                var alpha = (this.z + Radius) / (2 * Radius);
                ctx.arc(vpx + this.x, vpy + this.y, this.r * scale, 0, 2 * Math.PI, true);
                ctx.fillStyle = "rgba(255,255,255," + (alpha + 0.5) + ")";
                ctx.fill();
                ctx.restore();
            }
        }
        //著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。原文: https://www.w3cplus.com/canvas/create-3d-ball-with-canvas.html © w3cplus.com



        // 
        var a = new Animation();
    </script>
</body>

</html>